﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Collections;

namespace Common.Library
{
    /// <summary>
    /// 栈帮助类
    /// </summary>
    public class MyStack<T>:IEnumerable<T>, IDisposable
    {
        //栈顶指针
        private int _top = 0;
        //栈的大小
        private int _size = 0;
        //栈的数据
        private T[] _stack = null;

        public int Top
        {
            get { return _top; }
        }

        public int Size
        {
            get { return _size; }
        }

        public int Length
        {
            get { return _top; }
        }

        public T this[int index]
        {
            get { return _stack[index]; }
        }

        /// <summary>
        /// 栈的构造函数
        /// </summary>
        /// <param name="size">初始化栈的大小</param>
        public MyStack(int size)
        {
            _size = size;
            _top = 0;
            _stack = new T[size];
        }

        /// <summary>
        /// 栈是否为空
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty()
        {
            return _top == 0;
        }

        /// <summary>
        /// 栈是否已满
        /// </summary>
        /// <returns></returns>
        public bool IsFull()
        {
            return _top == _size;
        }

        /// <summary>
        /// 清除栈
        /// </summary>
        public void Clear()
        {
            _top = 0;
        }

        /// <summary>
        /// 入栈
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public bool Push(T node)
        {
            if (!IsFull())
            {
                _stack[_top] = node;
                _top++;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 出栈
        /// </summary>
        /// <returns></returns>
        public T Pop()
        {
            //此default关键字对于引用类型会返回空，对于数值类型会返回零
            T node = default(T);
            if (!IsEmpty())
            {
                _top--;
                node = _stack[_top];
                _stack[_top] = default(T);
            }
            return node;
        }


        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            _stack = null;
        }

        /// <summary>
        /// 迭代器，用于foreach迭代
        /// </summary>
        /// <returns></returns>
        public IEnumerator<T> GetEnumerator()
        {
            for (int i = 0; i < _stack.Length; i++)
            {
                if (_stack[i] != null)
                {
                    yield return _stack[i];
                }
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

}
